package it.free.maya.loadtest;

import it.free.maya.FacetedSearchResult;
import it.free.maya.SearchEngineQueryProxy;

import java.util.Date;
import java.util.Iterator;

import org.apache.log4j.Logger;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.response.FacetField.Count;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.client.solrj.SolrQuery;

/**
 * @author Stefano Falconetti
 */
public class VirtualUser implements Runnable {

	private static Logger logger = Logger.getLogger(VirtualUser.class);
	
	String myQuery = null;
	int myMaxTests = 0;
	long myTestInterval = 0L;
	boolean myVerbose = false;
	
	/**
	 * Class builder
	 * @param query is the query to execute
	 * @param maxTests is the nax number of test this virtual user has to run
	 * @param testInterval is the interval in millis between two tests executed by this virtual user
	 * @param verbose enable full tracing, too much expensive during tests
	 */
	public VirtualUser(String query, 
					   int maxTests, 
					   long testInterval, 
					   boolean verbose){
		
		this.myQuery = query;
		this.myMaxTests = maxTests;
		this.myTestInterval = testInterval;
		this.myVerbose = verbose;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
		
		int i=0;
		 
		for(; i< this.myMaxTests; i++){
		    try{
		    	doTest(i);	
				Thread.sleep(this.myTestInterval);
			}catch(Exception exc) {
				   logger.error("Thread " +  Thread.currentThread().getName() + " error:", exc);
				   break;
			}
		}
		logger.info(Thread.currentThread().getName() + "-| Test completed at " + (new Date()).toString() + ", success rate: " + i + "/" + this.myMaxTests);
	}

	/**
	 * Testig logic
	 * @param testNumberForThisVU is the test number for this virtual user
	 */
	private void doTest(int testNumberForThisVU) throws Exception{
		
		
		long millisBeforeQuery = System.currentTimeMillis();
		FacetedSearchResult facetedSearchResult = SearchEngineQueryProxy.getInstance().executeQuery(this.myQuery, 
																								    0, 
																								    20, 
																								    "product_price",
																								    SolrQuery.ORDER.desc,
																								    true,
																								    "product_name");
		long millisAfterQuery = System.currentTimeMillis() - millisBeforeQuery;
			
		logger.info(Thread.currentThread().getName() + "-| query millis: " + millisAfterQuery + " for " + facetedSearchResult.getSolrDocumentList().getNumFound() + " results, total test: " + MayaTesting.TESTS_EXECUTED);
		
		MayaTesting.TESTS_EXECUTED++;
			
		if(this.myVerbose){
		   SolrDocument solrDocument = null;
		   Iterator<FacetField> facetFieldsIterator = facetedSearchResult.getFacetFields().iterator();
		   FacetField facetField = null;
		   Iterator<Count> countIterator = null;
		   Count count = null;
		   
		   int counter = 1;
		   int categoryCounter = 1;

		   Iterator<SolrDocument> iterator = facetedSearchResult.getSolrDocumentList().iterator();
		   
		   while(iterator.hasNext()){
				 solrDocument = iterator.next();
				 logger.info("======== Product: " + (counter++) + " of " + facetedSearchResult.getSolrDocumentList().getNumFound() + " ========");
				 logger.info("--> product_uid=[" + solrDocument.getFieldValue("product_uid") + "]");
				 logger.info("sales_market=[" + solrDocument.getFieldValue("sales_market") + "]");
				 logger.info("vendor_code=[" + solrDocument.getFieldValue("vendor_code") + "]");
				 logger.info("product_code=[" + solrDocument.getFieldValue("product_code") + "]");
				 logger.info("product_name=[" + solrDocument.getFieldValue("product_name") + "]");
				 logger.info("product_brand=[" + solrDocument.getFieldValue("product_brand") + "]");
				 logger.info("product_detail_url=[" + solrDocument.getFieldValue("product_detail_url") + "]");
				 logger.info("product_description=[" + solrDocument.getFieldValue("product_description") + "]");
				 logger.info("product_image_url=[" + solrDocument.getFieldValue("product_image_url") + "]");
				 logger.info("product_price=[" + solrDocument.getFieldValue("product_price") + "]");
				 logger.info("product_reserved_price=[" + solrDocument.getFieldValue("product_reserved_price") + "]");
				 logger.info("product_availability=[" + solrDocument.getFieldValue("product_availability") + "]");
				 logger.info("shipping_costs=[" + solrDocument.getFieldValue("shipping_costs") + "]");
				 logger.info("shipping_rules=[" + solrDocument.getFieldValue("shipping_rules") + "]");
				 logger.info("shipping_rules_url=[" + solrDocument.getFieldValue("shipping_rules_url") + "]");
				 logger.info("vendor_name=[" + solrDocument.getFieldValue("vendor_name") + "]");
				 logger.info("ecommerce_web_site=[" + solrDocument.getFieldValue("ecommerce_web_site") + "]");
				 logger.info("vendor_logo_url=[" + solrDocument.getFieldValue("vendor_logo_url") + "]");
				 logger.info("vendor_web_site_url=[" + solrDocument.getFieldValue("vendor_web_site_url") + "]");
				 logger.info("vendor_address=[" + solrDocument.getFieldValue("vendor_address") + "]");
				 logger.info("vendor_zip_code=[" + solrDocument.getFieldValue("vendor_zip_code") + "]");
				 logger.info("vendor_city=[" + solrDocument.getFieldValue("vendor_city") + "]");
				 logger.info("vendor_district=[" + solrDocument.getFieldValue("vendor_district") + "]");
				 logger.info("vendor_contact_phone=[" + solrDocument.getFieldValue("vendor_contact_phone") + "]");
				 logger.info("vendor_contact_email=[" + solrDocument.getFieldValue("vendor_contact_email") + "]");
				 logger.info("vendor_country_code=[" + solrDocument.getFieldValue("vendor_country_code") + "]");
				 logger.info("currency_symbol=[" + solrDocument.getFieldValue("currency_symbol") + "]");
				 logger.info("currency_iso_code=[" + solrDocument.getFieldValue("currency_iso_code") + "]");
				 logger.info("category_description=[" + solrDocument.getFieldValue("category_description") + "]");
				 logger.info("subcategory_description=[" + solrDocument.getFieldValue("subcategory_description") + "]");
				 while(facetFieldsIterator.hasNext()){
					    facetField = facetFieldsIterator.next();
					    countIterator = facetField.getValues().iterator();
					    while(countIterator.hasNext()){
					    	  count = countIterator.next();
					          logger.info(categoryCounter + " category: [" + count.getName() + "], elements: [" + count.getCount() + "], query filter: [" + count.getAsFilterQuery() + "]");
					          categoryCounter++;
					    }
				  }
				  
				  logger.info("========");
			}		
		}
	}
}
